home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Mode:LISP; Package:(BOXER GLOBAL 1000); Base:10.; Fonts:CPTFONT -*-
-
- ;;; (C) Copyright 1985 Massachusetts Institute of Technology
- ;;;
- ;;; Permission to use, copy, modify, distribute, and sell this software
- ;;; and its documentation for any purpose is hereby granted without fee,
- ;;; provided that the above copyright notice appear in all copies and that
- ;;; both that copyright notice and this permission notice appear in
- ;;; supporting documentation, and that the name of M.I.T. not be used in
- ;;; advertising or publicity pertaining to distribution of the software
- ;;; without specific, written prior permission. M.I.T. makes no
- ;;; representations about the suitability of this software for any
- ;;; purpose. It is provided "as is" without express or implied warranty.
- ;;;
-
- ;;;constants
-
- #-ti(defconst PI 3.14592653) ;already defined by TI
-
- (defconst pi)
-
- (defconst TO-DEGREES (// 180 pi))
-
- (defboxer-function bu: () )
-
- (defboxer-function bu:pi () PI)
-
- ;;; What the evaluator understands as logical values
-
- (EVAL-WHEN (LOAD)
- (SHADOW '(TRUE FALSE) 'BOXER)
- )
-
- (DEFCONST TRUE 'BU:TRUE)
-
- (DEFCONST FALSE 'BU:FALSE)
-
- (DEFUN TRUE () TRUE)
- (DEFUN FALSE () FALSE)
-
- ;;; useful to have around for comparing things
-
- (DEFCONST TRUE-EVBOX (MAKE-EVDATA ROWS `(,(MAKE-EVROW-FROM-ENTRY 'BU:TRUE))))
-
- (DEFCONST FALSE-EVBOX (MAKE-EVDATA ROWS `(,(MAKE-EVROW-FROM-ENTRY 'BU:FALSE))))
-
- ;;; Variables for modifying data box arithmetic behavior
-
- (DEFVAR *NON-MATCHING-BOX-ARITHMETIC-ACTION* ':ERROR
- "Specifies how to handle situations when the args to arithmetic operations have
- differing numbers of elements. Currently allowed values are :ERROR (signal an error),
- :FILL (fill smaller boxes with zeros), and :TRUNCATE (ignore extra elements in the larger
- boxes). ")
-
- ;;; is it live, or is it a number
- (DEFBOXER-FUNCTION BU:NUMBER? (THING)
- (BOXER-BOOLEAN (BOXER-NUMBER? THING)))
-
- (DEFUN BOXER-NUMBER? (THING)
- (OR (NUMBERP THING)
- (NUMBER-BOX? THING)))
-
- ;;; Generic operation macros
-
- (DEFUN TYPIFY-ARGS (&REST ARGS)
- "Returns :NUMBER if all the args are numbers or :BOX if ANY arg is a box or NIL"
- (IF (NULL (SUBSET #'(LAMBDA (X) (OR (EVAL-BOX? X) (EVAL-PORT? X))) ARGS))
- ':NUMBER
- ':BOX))
-
- (DEFMACRO ARG-DISPATCH (OP . ARGS)
- `(SELECTQ (TYPIFY-ARGS ,@ARGS)
- ((:BOX)
- ;; at least one arg is a box so use the box arithmetic routines
- (FUNCALL ',(INTERN (STRING-APPEND "DATA-BOX-" (STRING `,OP))) ,@ARGS))
- ((:NUMBER)
- ;; assume that all the args are numbers (may want to put an error check here)
- (FUNCALL ',OP ,@ARGS))
- (OTHERWISE
- (FERROR "The args, ~A, to ~A were not boxes or numbers" (LIST ,@ARGS) ',OP))))
-
- (DEFMETHOD (BOX :ELEMENTS) ()
- (LOOP FOR ROW IN (TELL SELF :ROWS)
- APPENDING (TELL ROW :ELEMENTS)))
-
- ;;; Boxer versions of some operators (the others we import directly)
-
- (DEFUN BOXER-> (A B)
- (BOXER-BOOLEAN
- (COND ((> A B) t)
- (T NIL))))
-
- (DEFUN BOXER-< (A B)
- (BOXER-BOOLEAN
- (COND ((< A B) t)
- (T NIL))))
-
- (DEFUN BOXER- (A B)
- (BOXER-BOOLEAN
- (COND (( A B) t)
- (T NIL))))
-
- (DEFUN BOXER- (A B)
- (BOXER-BOOLEAN
- (COND (( A B) t)
- (T NIL))))
-
- (DEFUN BOXER->= (A B)
- (BOXER-BOOLEAN
- (COND ((>= A B) t)
- (T NIL))))
-
- (DEFUN BOXER-<= (A B)
- (BOXER-BOOLEAN
- (COND ((<= A B) t)
- (T NIL))))
-
- (DEFUN BOXER-QUOTIENT (divisor dividend)
- (//$ (float divisor) (float dividend)))
-
- (DEFUN BOXER-EXPT (A B)
- (if (and (minusp a)
- (floatp b)
- (zerop (- b (fix b))))
- (expt a (fix b))
- (expt a b)))
-
- ; (IF (AND (TYPEP A ':FIX) (TYPEP B ':FIX))
- ; (^ A B)
- ; (^$ (FLOAT A) (FLOAT B))))
-
- (DEFUN BOXER-ATAN (Y X)
- (* (ATAN Y X) TO-DEGREES))
-
- (DEFUN BOXER-ZERO? (N)
- (BOXER-BOOLEAN (ZEROP N)))
-
- (DEFUN BOXER-PLUS? (N)
- (BOXER-BOOLEAN (PLUSP N)))
-
- (DEFUN BOXER-MINUS? (N)
- (BOXER-BOOLEAN (MINUSP N)))
-
- (DEFUN BOXER-ODD? (N)
- (BOXER-BOOLEAN (when (fixp n) (ODDP N))))
-
- (DEFUN BOXER-EVEN? (N)
- (BOXER-BOOLEAN (when (fixp n)(EVENP N))))
-
- ;;; Data box arithmetic
-
- (DEFUN COMPARE-BOX-LENGTHS (&REST BOXES)
- (LOOP WITH SAME-LENGTH = T
- WITH CURRENT-LENGTH = (GET-BOX-LENGTH-IN-ROWS (CAR BOXES))
- FOR BOX IN BOXES
- FOR LENGTH = (GET-BOX-LENGTH-IN-ROWS BOX)
- UNLESS (= LENGTH CURRENT-LENGTH)
- DO (SETQ SAME-LENGTH NIL)
- MINIMIZE LENGTH INTO SMALLEST-LENGTH
- MAXIMIZE LENGTH INTO LARGEST-LENGTH
- DO (SETQ CURRENT-LENGTH LENGTH)
- FINALLY (RETURN (VALUES SAME-LENGTH SMALLEST-LENGTH LARGEST-LENGTH))))
-
- (DEFUN COMPARE-ROW-LENGTHS (&REST ROWS)
- (LOOP WITH CURRENT-LENGTH = (LENGTH (CAR ROWS))
- FOR ROW IN (CDR ROWS)
- FOR LENGTH = (LENGTH ROW)
- WHEN ( LENGTH CURRENT-LENGTH)
- RETURN NIL
- FINALLY (RETURN T)))
-
- (DEFUN COLLECT-NTHS (N LISTS)
- (LOOP FOR LIST IN LISTS
- COLLECTING (NTH N LIST)))
-
- (DEFUN MAP-OVER-ROW-ELEMENTS (FCN ROWS)
- (MAKE-EVROW-FROM-ENTRIES
- (SELECTQ *NON-MATCHING-BOX-ARITHMETIC-ACTION*
- ((:TRUNCATE) (LEXPR-FUNCALL #'MAPCAR FCN ROWS))
- ((:FILL)
- (LOOP FOR INDEX FROM 0 TO (1- (LEXPR-FUNCALL #'MAX (MAPCAR #'LENGTH ROWS)))
- COLLECTING (APPLY FCN (MAPCAR #'(LAMBDA (X) (OR (NTH INDEX X) 0)) ROWS))))
- (OTHERWISE (IF (LEXPR-FUNCALL #'COMPARE-ROW-LENGTHS ROWS)
- (LEXPR-FUNCALL #'MAPCAR FCN ROWS)
- (FERROR "The rows, ~A have different numbers of elements" ROWS))))))
-
- (DEFUN MAP-OVER-BOXS-ELEMENTS (FCN BOXES)
- "Mapping function for functions with mutiple box arguments"
- (LET ((ROWS (MULTIPLE-VALUE-BIND (SAME-SIZE MIN-SIZE MAX-SIZE)
- (LEXPR-FUNCALL #'COMPARE-BOX-LENGTHS BOXES)
- (SELECTQ *NON-MATCHING-BOX-ARITHMETIC-ACTION*
- ((:TRUNCATE)
- (LOOP WITH ROWS-LISTS = (MAPCAR #'GET-BOX-ROWS BOXES)
- FOR INDEX FROM 0 TO (1- MIN-SIZE)
- FOR ROWS = (COLLECT-NTHS INDEX ROWS-LISTS)
- COLLECTING (MAP-OVER-ROW-ELEMENTS FCN ROWS)))
- ((:FILL)
- (LOOP WITH ROWS-LISTS = (MAPCAR #'GET-BOX-ROWS BOXES)
- FOR INDEX FROM 0 TO (1- MAX-SIZE)
- FOR ROWS = (COLLECT-NTHS INDEX ROWS-LISTS)
- COLLECTING (MAP-OVER-ROW-ELEMENTS FCN ROWS)))
- (OTHERWISE
- (IF (NULL SAME-SIZE)
- (FERROR "The boxes ,~A have different numbers of rows" BOXES)
- (LOOP WITH ROWS-LISTS = (MAPCAR #'GET-BOX-ROWS BOXES)
- FOR INDEX FROM 0 TO (1- MIN-SIZE)
- FOR ROWS = (COLLECT-NTHS INDEX ROWS-LISTS)
- COLLECTING (MAP-OVER-ROW-ELEMENTS FCN ROWS))))))))
- (IF (AND (= 1 (LENGTH ROWS)) (= 1 (EVROW-LENGTH-IN-ELEMENTS (CAR ROWS)))
- (NUMBERP (GET-FIRST-ELEMENT-IN-EVROW (CAR ROWS))))
- ;;we flatten boxes with single numbers in them into the numbers
- (GET-FIRST-ELEMENT-IN-EVROW (CAR ROWS))
- (MAKE-EVDATA ROWS ROWS))))
-
- (DEFUN MAP-OVER-BOX-ELEMENTS (FCN BOX)
- "Mapping-function for functions which take only a single box argument. "
- (LET ((ROWS (LOOP FOR ROW IN (GET-BOX-ROWS BOX)
- COLLECTING (MAKE-EVROW-FROM-ENTRIES (MAPCAR FCN ROW)))))
- (IF (AND (= 1 (LENGTH ROWS)) (= 1 (EVROW-LENGTH-IN-ELEMENTS (CAR ROWS)))
- (NUMBERP (GET-FIRST-ELEMENT-IN-EVROW (CAR ROWS))))
- ;;we flatten boxes with single numbers in them into the numbers
- (GET-FIRST-ELEMENT-IN-EVROW (CAR ROWS))
- (MAKE-EVDATA ROWS ROWS))))
-
- ;;; Multiple data box argument functions
-
- (DEFUN DATA-BOX-PLUS (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'PLUS BOXES))
-
- (DEFUN DATA-BOX-DIFFERENCE (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'DIFFERENCE BOXES))
-
- (DEFUN DATA-BOX-TIMES (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'TIMES BOXES))
-
- (DEFUN DATA-BOX-BOXER-QUOTIENT (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER-QUOTIENT BOXES))
-
- (DEFUN DATA-BOX-REMAINDER (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'REMAINDER BOXES))
-
- (DEFUN DATA-BOX-BOXER-EXPT (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER-EXPT BOXES))
-
- (DEFUN DATA-BOX-BOXER-ATAN (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER-ATAN BOXES))
-
- (DEFUN DATA-BOX-GCD (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'GCD BOXES))
-
- (DEFUN DATA-BOX-MAX (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'MAX BOXES))
-
- (DEFUN DATA-BOX-MIN (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'MIN BOXES))
-
- (DEFUN DATA-BOX-BOXER-> (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER-> BOXES))
-
- (DEFUN DATA-BOX-BOXER-< (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER-< BOXES))
-
- (DEFUN DATA-BOX-BOXER- (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER- BOXES))
-
- (DEFUN DATA-BOX-BOXER- (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER- BOXES))
-
- (DEFUN DATA-BOX-BOXER->= (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER->= BOXES))
-
- (DEFUN DATA-BOX-BOXER-<= (&REST BOXES)
- (MAP-OVER-BOXS-ELEMENTS #'BOXER-<= BOXES))
-
- ;;; Functions which take a single data box argument
- ;;; single argument predicates
-
- (DEFUN DATA-BOX-BOXER-MINUS? (BOX)
- (MAP-OVER-BOX-ELEMENTS #'BOXER-MINUS? BOX))
-
- (DEFUN DATA-BOX-BOXER-PLUS? (BOX)
- (MAP-OVER-BOX-ELEMENTS #'BOXER-PLUS? BOX))
-
- (DEFUN DATA-BOX-BOXER-ZERO? (BOX)
- (MAP-OVER-BOX-ELEMENTS #'BOXER-ZERO? BOX))
-
- (DEFUN DATA-BOX-BOXER-EVEN? (BOX)
- (MAP-OVER-BOX-ELEMENTS #'BOXER-EVEN? BOX))
-
- (DEFUN DATA-BOX-BOXER-ODD? (BOX)
- (MAP-OVER-BOX-ELEMENTS #'BOXER-ODD? BOX))
-
- ;;; single argument other stuff
- (DEFUN DATA-BOX-SIND (BOX)
- (MAP-OVER-BOX-ELEMENTS #'SIND BOX))
-
- (DEFUN DATA-BOX-COSD (BOX)
- (MAP-OVER-BOX-ELEMENTS #'COSD BOX))
-
- (DEFUN DATA-BOX-RANDOM (BOX)
- (MAP-OVER-BOX-ELEMENTS #'RANDOM BOX))
-
- (DEFUN DATA-BOX-ABS (BOX)
- (MAP-OVER-BOX-ELEMENTS #'ABS BOX))
-
- (DEFUN DATA-BOX-SQRT (BOX)
- (MAP-OVER-BOX-ELEMENTS #'SQRT BOX))
-
- (DEFUN DATA-BOX-EXP (BOX)
- (MAP-OVER-BOX-ELEMENTS #'EXP BOX))
-
- (DEFUN DATA-BOX-LOG (BOX)
- (MAP-OVER-BOX-ELEMENTS #'LOG BOX))
-
- (DEFUN DATA-BOX-ROUND (BOX)
- (MAP-OVER-BOX-ELEMENTS #'ROUND BOX))
-
- (DEFUN DATA-BOX-FLOOR (BOX)
- (MAP-OVER-BOX-ELEMENTS #'FLOOR BOX))
-
- (DEFUN DATA-BOX-CEILING (BOX)
- (MAP-OVER-BOX-ELEMENTS #'CEILING BOX))
-
- ;;; LOGICAL and support functions
-
- (DEFBOXER-FUNCTION BU:FALSE ()
- FALSE)
-
- (DEFBOXER-FUNCTION BU:TRUE ()
- TRUE)
-
- (defun boxer-boolean (t-or-nil)
- (if t-or-nil TRUE FALSE))
-
- ;;; these are for internal use and return the values T or NIL (NOT TRUE or FALSE)
- (defun TRUE? (true-or-false)
- (when (eval-port? true-or-false) (setq true-or-false (get-port-target true-or-false)))
- (COND ((EVAL-BOX? TRUE-OR-FALSE)
- (BOX-EQUAL? TRUE-OR-FALSE TRUE-EVBOX))
- (T (STRING-EQUAL TRUE-OR-FALSE TRUE))))
-
- (defun FALSE? (true-or-false)
- (when (eval-port? true-or-false) (setq true-or-false (get-port-target true-or-false)))
- (COND ((EVAL-BOX? TRUE-OR-FALSE)
- (box-equal? true-or-false FALSE-EVBOX))
- (T (STRING-EQUAL TRUE-OR-FALSE FALSE))))
-
- ;;; The Boxer functions
-
- (DEFBOXER-FUNCTION BU:NOT (TRUE-OR-FALSE)
- (IF (TRUE? TRUE-OR-FALSE) FALSE TRUE))
-
- (DEFUN BOXER-= (A B)
- (COND ((AND (NUMBER-BOX? A) (NUMBER-BOX? B))
- (= (NUMBERIZE A) (NUMBERIZE B)))
- ((OR (STRINGP A) (STRINGP B)) (EQUAL A B))
- ((OR (SYMBOLP A) (SYMBOLP B)) (EQUAL A B))
- ((AND (or (EVAL-BOX? A) (eval-port? a)) (or (EVAL-BOX? B) (eval-port? b)))
- (BOX-EQUAL? A B))
- (T NIL)))
-
- (DEFBOXER-FUNCTION BU:= (A B)
- (BOXER-BOOLEAN (BOXER-= A B)))
-
- (DEFBOXER-FUNCTION BU: (A B)
- (BOXER-BOOLEAN (NOT (BOXER-= A B))))
-
- (DEFBOXER-FUNCTION BU:AND (A B)
- (BOXER-BOOLEAN (AND (TRUE? A)
- (TRUE? B))))
-
- (DEFBOXER-FUNCTION BU:OR (A B)
- (BOXER-BOOLEAN (OR (TRUE? A)
- (TRUE? B))))
-
- ;;; And into Boxer we go....
- ;;; single argument predicates
-
- (DEFBOXER-FUNCTION BU:PLUS? (X)
- (arg-dispatch BOXER-PLUS? X))
-
- (DEFBOXER-FUNCTION BU:MINUS? (X)
- (arg-dispatch BOXER-MINUS? X))
-
- (DEFBOXER-FUNCTION BU:ZERO? (X)
- (ARG-DISPATCH BOXER-ZERO? X))
-
- (DEFBOXER-FUNCTION BU:EVEN? (X)
- (arg-dispatch BOXER-EVEN? X))
-
- (DEFBOXER-FUNCTION BU:ODD? (X)
- (arg-dispatch BOXER-ODD? X))
-
- ;;; single argument other stuff
-
- (DEFBOXER-FUNCTION BU:CEILING (FLOAT)
- (ARG-DISPATCH CEILING FLOAT))
-
- (defboxer-function bu:round (float)
- (arg-dispatch round float))
-
- (defboxer-function bu:floor (float)
- (arg-dispatch floor float))
-
- (DEFBOXER-FUNCTION BU:MINUS (BOX)
- (arg-dispatch BOXER-MINUS BOX))
-
- (DEFBOXER-FUNCTION BU:RANDOM (LESS-THAN)
- (arg-dispatch RANDOM LESS-THAN))
-
- (DEFBOXER-FUNCTION BU:ABS (X)
- (arg-dispatch ABS X))
-
- (DEFBOXER-FUNCTION BU:SQRT (X)
- (arg-dispatch SQRT X))
-
- (DEFBOXER-FUNCTION BU:EXP (X)
- (arg-dispatch EXP X))
-
- (DEFBOXER-FUNCTION BU:LOG (X)
- (arg-dispatch LOG X))
-
- (DEFBOXER-FUNCTION BU:SIN (ANGLE)
- (arg-dispatch SIND ANGLE))
-
- (DEFBOXER-FUNCTION BU:COS (ANGLE)
- (arg-dispatch COSD ANGLE))
-
- ;;; Two argument predicates
-
- (DEFBOXER-FUNCTION BU:< (A B)
- (arg-dispatch BOXER-< A B))
-
- (DEFBOXER-FUNCTION BU:> (A B)
- (arg-dispatch BOXER-> A B))
-
- (DEFBOXER-FUNCTION BU: (A B)
- (arg-dispatch BOXER- A B))
-
- (DEFBOXER-FUNCTION BU: (A B)
- (arg-dispatch BOXER- A B))
-
- (DEFBOXER-FUNCTION BU:<= (A B)
- (arg-dispatch BOXER-<= A B))
-
- (DEFBOXER-FUNCTION BU:>= (A B)
- (arg-dispatch BOXER->= A B))
-
- ;;; Two argument other stuff
-
- (DEFBOXER-FUNCTION BU:PLUS (A B)
- (arg-dispatch PLUS A B))
-
- (DEFBOXER-FUNCTION BU:+ (A B)
- (arg-dispatch PLUS A B))
-
- (DEFBOXER-FUNCTION BU:DIFFERENCE (A B)
- (arg-dispatch DIFFERENCE A B))
-
- (DEFBOXER-FUNCTION BU:- (A B)
- (arg-dispatch DIFFERENCE A B))
-
- (DEFBOXER-FUNCTION BU:TIMES (A B)
- (arg-dispatch TIMES A B))
-
- (DEFBOXER-FUNCTION BU:* (A B)
- (arg-dispatch TIMES A B))
-
- (DEFBOXER-FUNCTION BU:QUOTIENT (A B)
- (arg-dispatch BOXER-QUOTIENT A B))
-
- (DEFBOXER-FUNCTION BU:// (A B)
- (arg-dispatch BOXER-QUOTIENT A B))
-
- (DEFBOXER-FUNCTION BU:REMAINDER (A B)
- (arg-dispatch REMAINDER A B))
-
- (DEFBOXER-FUNCTION BU:EXPT (A B)
- (arg-dispatch BOXER-EXPT A B))
-
- (DEFBOXER-FUNCTION BU:ATAN (A B)
- (arg-dispatch BOXER-ATAN A B))
-
- (DEFBOXER-FUNCTION BU:^ (A B)
- (arg-dispatch BOXER-EXPT A B))
-
- (DEFBOXER-FUNCTION BU:GCD (A B)
- (arg-dispatch GCD A B))
-
- (DEFBOXER-FUNCTION BU:MIN (A B)
- (arg-dispatch MIN A B))
-
- (DEFBOXER-FUNCTION BU:MAX (A B)
- (ARG-DISPATCH MAX A B))
-
- ;;; rational stuff
- (defun data-box-rational (a)
- (map-over-box-elements #'rational a))
-
- (defun data-box-float (a)
- (map-over-box-elements #'float a))
-
- (defun data-box-numerator (a)
- (map-over-box-elements #'numerator a))
-
- (defun data-box-denominator (a)
- (map-over-box-elements #'denominator a))
-
- (defboxer-function bu:rational (a)
- (arg-dispatch rational a))
-
- (defboxer-function bu:float (a)
- (arg-dispatch float a))
-
- (defboxer-function bu:numerator (a)
- (arg-dispatch numerator a))
-
- (defboxer-function bu:denominator (a)
- (arg-dispatch denominator a))
-
- (load "es://usr//emstsun//guest//load-box.lisp")
-